package cc.vv.baselibrary.util;

import android.app.Activity;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.text.Html;
import android.text.Spanned;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Hashtable;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import cc.vv.lkbasecomponent.base.app.LKBaseApplication;
import cc.vv.lklibrary.log.LogOperate;

/**
 * 常用方法聚集类
 *
 * @author nanPengFei
 */
public class LKCommonUtil {

    public static void runOnUIThread(Runnable runnable) {
        LKBaseApplication.getHandler().postDelayed(runnable, 0);
    }

    /**
     * 判断是否含有特殊字符
     *
     * @param str
     * @return true为包含，false为不包含
     */
    public static boolean isSpecialChar(String str) {
        String regEx = "[- _`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？]|\n|\r|\t";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(str);
        return m.find();
    }

    /**
     * 根据id获取dimens中定义的dimen
     *
     * @param resId 指向dimen的id
     * @return float
     */
    public static float getDimens(int resId) {
        return LKBaseApplication.getApplication().getResources().getDimension(resId);
    }

    /**
     * 根据id获取strings中定义的string
     *
     * @param resId 指向string的id
     * @return String
     */
    public static String getString(int resId) {
        return LKBaseApplication.getApplication().getResources().getString(resId);
    }

    /**
     * 获取图片资源
     *
     * @param resId
     * @return Drawable
     */
    public static Drawable getDrawable(int resId) {
        return LKBaseApplication.getApplication().getResources().getDrawable(resId);
    }

    /**
     * 获取字符串数组资源
     *
     * @param resId
     * @return String[]
     */
    public static String[] getStringArray(int resId) {
        return LKBaseApplication.getApplication().getResources().getStringArray(resId);
    }

    /**
     * 根据手机分辨率转dp为px
     *
     * @param dpValue dp值
     * @return int
     */
    public static int dip2px(float dpValue) {
        final float scale = LKBaseApplication.getApplication().getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    /**
     * 根据手机的分辨率转px为 dp
     *
     * @param pxValue px值
     * @return int
     */
    public static int px2dip(float pxValue) {
        final float scale = LKBaseApplication.getApplication().getResources().getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5f);
    }

    /**
     * 将px值转换为sp值
     *
     * @param pxValue （DisplayMetrics类中属性scaledDensity）
     * @return int
     */
    public static int px2sp(float pxValue) {
        final float fontScale = LKBaseApplication.getApplication().getResources().getDisplayMetrics().scaledDensity;
        return (int) (pxValue / fontScale + 0.5f);
    }

    /**
     * 将sp值转换为px值
     *
     * @param spValue （DisplayMetrics类中属性scaledDensity）
     * @return
     */
    public static int sp2px(float spValue) {
        final float fontScale = LKBaseApplication.getApplication().getResources().getDisplayMetrics().scaledDensity;
        return (int) (spValue * fontScale + 0.5f);
    }

    /**
     * 获取手机状态栏高度
     *
     * @return int
     */
    public static int getStatusBarHeight() {
        Class<?> c = null;
        Object obj = null;
        java.lang.reflect.Field field = null;
        int x = 0;
        int statusBarHeight = LKCommonUtil.dip2px(18);
        try {
            c = Class.forName("com.android.internal.R$dimen");
            obj = c.newInstance();
            field = c.getField("status_bar_height");
            x = Integer.parseInt(field.get(obj).toString());
            statusBarHeight = LKBaseApplication.getApplication().getResources().getDimensionPixelSize(x);
            return statusBarHeight;
        } catch (Exception e) {
            LogOperate.e(e.getMessage(), e);
        }
        return statusBarHeight;
    }

    /**
     * 将指定childView从它的父View中移除
     *
     * @param child
     */
    public static void removeSelfFromParent(View child) {
        if (child != null) {
            ViewParent parent = child.getParent();
            if (parent instanceof ViewGroup) {
                ViewGroup group = (ViewGroup) parent;
                // 将child从父view当中移除
                group.removeView(child);
            }
        }
    }

    /**
     * 获取屏幕的宽度
     *
     * @return
     */
    public static int getScreenWidth() {
        Resources resources = LKBaseApplication.getApplication().getResources();
        DisplayMetrics displayMetrics = resources.getDisplayMetrics();
        return displayMetrics.widthPixels;
    }

    /**
     * 获取屏幕的高度
     *
     * @return
     */
    public static int getScreenHeight() {
        Resources resources = LKBaseApplication.getApplication().getResources();
        DisplayMetrics displayMetrics = resources.getDisplayMetrics();
        return displayMetrics.heightPixels;
    }

    /**
     * 获取屏幕中控件顶部位置的高度--即控件顶部的Y点
     *
     * @return
     */
    public static int getScreenViewTopHeight(View view) {
        return view.getTop();
    }

    /**
     * 获取屏幕中控件底部位置的高度--即控件底部的Y点
     *
     * @return
     */
    public static int getScreenViewBottomHeight(View view) {
        return view.getBottom();
    }

    /**
     * 获取屏幕中控件左侧的位置--即控件左侧的X点
     *
     * @return
     */
    public static int getScreenViewLeftHeight(View view) {
        return view.getLeft();
    }

    /**
     * 获取屏幕中控件右侧的位置--即控件右侧的X点
     *
     * @return
     */
    public static int getScreenViewRightHeight(View view) {
        return view.getRight();
    }


    /**
     * 判断是否为手机号
     *
     * @param phoneStr
     * @return
     */
    public static boolean isPhone(String phoneStr) {
        if (TextUtils.isEmpty(phoneStr)) {
            return false;
        } else {
            final String str = "^((13[0-9])|(15[^4,\\D])|(17[0-9])|(18[0-9]))\\d{8}$";
            String replace = phoneStr.replace(" ", "");
            return replace.matches(str);
        }
    }

    /**
     * 判断是否为纳税人识别号
     *
     * @param phoneStr
     * @return
     */
    public static boolean isCompanyNum(String phoneStr) {
        if (TextUtils.isEmpty(phoneStr)) {
            return false;
        } else {
            final String str = "^((\\d{6}[0-9A-Z]{9})|([0-9A-Za-z]{2}\\d{6}[0-9A-Za-z]{10}))$";
            String replace = phoneStr.replace(" ", "");
            return replace.matches(str);
        }
    }

    /**
     * 判断身份证
     *
     * @param idCard
     * @return
     */
//    public static boolean isIdCard(String idCard) {
//        String str = "([1-9]\\d{5}(19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[\\dx])|([1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3})";
//        if (!TextUtils.isEmpty(idCard) && (idCard.length() == 15 || idCard.length() == 18)) {
//            idCard = idCard.replace(" ", "");
//            String str = "^[1-9]\\d{5}(18|19|([23]\\d))\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$";
//            if (idCard.length() == 15) {
//                str = "^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{2}$";
//            }
//            return idCard.matches(str);
//        } else {
//            return false;
//        }
//    }

    /**
     * 判断email格式是否正确
     *
     * @param email
     * @return
     */
    public static boolean isEmail(String email) {
        final String str = "^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$";
        Pattern p = Pattern.compile(str);
        Matcher m = p.matcher(email);
        return m.matches();
    }

    /**
     * 检索所有@开始,空格结束的文字
     *
     * @param string
     * @return
     */
    public static ArrayList<String> checkStr(String string) {
        ArrayList<String> mateStrs = new ArrayList<>();
        mateStrs.clear();
        Pattern pattern = Pattern.compile("\\@\\w+ ");
        Matcher matcher = pattern.matcher(string);
        while (matcher.find()) {
            String mateStr = matcher.group().trim();
            if (!TextUtils.isEmpty(mateStr) && mateStr.length() > 1) {
                mateStrs.add(mateStr.substring(1));
            }
        }
        return mateStrs;
    }

    /**
     * 特殊字符判断---
     *
     * @param str
     * @return
     */
    public static boolean checkPassword(String str) {
        final String regEx = "^[a-zA-Z0-9]+$";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(str);
        return m.matches();
    }

    /**
     * 由数字和字母组成，并且要同时含有数字和字母，且长度要在8-16位之间
     *
     * @param str
     * @return
     */
    public static boolean checkPassword1(String str) {
        final String regEx = "^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8,16}$";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(str);
        return m.matches();
    }

    /**
     * 获取底部虚拟键盘的高度
     */
    public static int getBottomKeyboardHeight(Activity activity) {
        DisplayMetrics dm = new DisplayMetrics();
        activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
        return getScreenHeight() - dm.heightPixels;
    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    public static final Spanned fromHtml(String text) {
//        final int version = Build.VERSION.SDK_INT;
//        final int mineVersion = 19;
//        if (version >= mineVersion) {
//            return Html.fromHtml(text, Html.FROM_HTML_MODE_COMPACT);
//        } else {
//            return Html.fromHtml(text);
//        }
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
            return Html.fromHtml(text, Html.FROM_HTML_MODE_LEGACY);
        } else {
            return Html.fromHtml(text);
        }
    }

    /**
     * 判断身份证
     *
     * @param idCard
     * @return
     */
    public static boolean isIdCard(String idCard) {
        boolean isCorrect = false;
        try {
            if (!TextUtils.isEmpty(idCard) && (idCard.length() == 15 || idCard.length() == 18)) {
                String idCardNum = "";
                if (idCard.length() == 18) {
                    idCardNum = idCard.substring(0, 17);
                } else if (idCard.length() == 15) {
                    idCardNum = idCard.substring(0, 6) + "19" + idCard.substring(6, 15);
                }
                if (isNumeric(idCardNum)) {
                    String strYear = idCardNum.substring(6, 10);// 年份
                    String strMonth = idCardNum.substring(10, 12);// 月份
                    String strDay = idCardNum.substring(12, 14);// 日期
                    if (isDate(strYear + "-" + strMonth + "-" + strDay)) {
                        GregorianCalendar gc = new GregorianCalendar();
                        SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd", Locale.CHINESE);
                        if (!((gc.get(Calendar.YEAR) - Integer.parseInt(strYear)) > 150
                                || (gc.getTime().getTime() - s.parse(strYear + "-" + strMonth + "-" + strDay).getTime()) < 0)) {
                            if (!(Integer.parseInt(strMonth) > 12 || Integer.parseInt(strMonth) == 0)) {
                                if (!(Integer.parseInt(strDay) > 31 || Integer.parseInt(strDay) == 0)) {
                                    Hashtable areacode = getAreaCode();
                                    if (null != areacode.get(idCardNum.substring(0, 2))) {
                                        if (isVarifyCode(idCardNum, idCard)) {
                                            isCorrect = true;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            LogOperate.e(e.getMessage(), e);
        }
        return isCorrect;
    }

    /**
     * 判断第18位校验码是否正确 第18位校验码的计算方式： 1. 对前17位数字本体码加权求和 公式为：S = Sum(Ai * Wi), i =
     * 0, ... , 16 其中Ai表示第i个位置上的身份证号码数字值，Wi表示第i位置上的加权因子，其各位对应的值依次为： 7 9 10 5 8 4
     * 2 1 6 3 7 9 10 5 8 4 2 2. 用11对计算结果取模 Y = mod(S, 11) 3. 根据模的值得到对应的校验码
     * 对应关系为： Y值：     0  1  2  3  4  5  6  7  8  9  10 校验码： 1  0  X  9  8  7  6
     * 5  4  3   2
     *
     * @param idCardNum
     * @param idCard
     * @return
     */
    private static boolean isVarifyCode(String idCardNum, String idCard) {
        String[] VarifyCode = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"};
        String[] Wi = {"7", "9", "10", "5", "8", "4", "2", "1", "6", "3", "7", "9", "10", "5", "8", "4", "2"};
        int sum = 0;
        for (int i = 0; i < 17; i++) {
            sum = sum + Integer.parseInt(String.valueOf(idCardNum.charAt(i))) * Integer.parseInt(Wi[i]);
        }
        int modValue = sum % 11;
        String strVerifyCode = VarifyCode[modValue];
        idCardNum = idCardNum + strVerifyCode;
        if (idCard.length() == 18) {
            if (!idCardNum.equals(idCard)) {
                return false;

            }
        }
        return true;
    }

    /**
     * 将所有地址编码保存在一个Hashtable中
     *
     * @return Hashtable 对象
     */

    private static Hashtable getAreaCode() {
        Hashtable<String, String> hashtable = new Hashtable<>();
        hashtable.put("11", "北京");
        hashtable.put("12", "天津");
        hashtable.put("13", "河北");
        hashtable.put("14", "山西");
        hashtable.put("15", "内蒙古");
        hashtable.put("21", "辽宁");
        hashtable.put("22", "吉林");
        hashtable.put("23", "黑龙江");
        hashtable.put("31", "上海");
        hashtable.put("32", "江苏");
        hashtable.put("33", "浙江");
        hashtable.put("34", "安徽");
        hashtable.put("35", "福建");
        hashtable.put("36", "江西");
        hashtable.put("37", "山东");
        hashtable.put("41", "河南");
        hashtable.put("42", "湖北");
        hashtable.put("43", "湖南");
        hashtable.put("44", "广东");
        hashtable.put("45", "广西");
        hashtable.put("46", "海南");
        hashtable.put("50", "重庆");
        hashtable.put("51", "四川");
        hashtable.put("52", "贵州");
        hashtable.put("53", "云南");
        hashtable.put("54", "西藏");
        hashtable.put("61", "陕西");
        hashtable.put("62", "甘肃");
        hashtable.put("63", "青海");
        hashtable.put("64", "宁夏");
        hashtable.put("65", "新疆");
        hashtable.put("71", "台湾");
        hashtable.put("81", "香港");
        hashtable.put("82", "澳门");
        hashtable.put("91", "国外");
        return hashtable;
    }

    /**
     * 判断字符串是否为数字,0-9重复0次或者多次
     *
     * @param idCardNum
     * @return
     */
    private static boolean isNumeric(String idCardNum) {
        Pattern pattern = Pattern.compile("[0-9]*");
        Matcher isNum = pattern.matcher(idCardNum);
        return isNum.matches();
    }

    /**
     * 判断字符串出生日期是否符合正则表达式：包括年月日，闰年、平年和每月31天、30天和闰月的28天或者29天
     *
     * @param strDate
     * @return
     */
    private static boolean isDate(String strDate) {
        Pattern pattern = Pattern.compile(
                "^((\\d{2}(([02468][048])|([13579][26]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))?$");
        Matcher m = pattern.matcher(strDate);
        if (m.matches()) {
            return true;
        } else {
            return false;
        }
    }


}
